
#include "../../../container/hash_map/clib_container_hash_map.h"
#include "../../../hash/crc/clib_hash_crc32.h"
#include <malloc.h>

static struct clib_container_hash_map *map;


static void show() {

    size_t current_size = clib_container_hash_map_get_current_size(map);
    printf("当前大小 %zu\n", current_size);

    void *keys[current_size];

    int size = clib_container_hash_map_get_keys(map, keys);
    if (size != current_size) {
        //异常
        printf("clib_container_hash_map_get_keys error\n");
        return;
    }

    printf("keys: \n");
    for (int i = 0; i < size; ++i) {
        printf("%u ", *(clib_uint32_t *) keys[i]);
    }
    printf("\n");
    printf("values: \n");
    for (int i = 0; i < size; ++i) {
        void *result;
        int code = clib_container_hash_map_get(map, keys[i], &result);
        if (code != CLIB_RES_OK) {
            printf("clib_container_hash_map_get error\n");
            return;
        }
        printf("%u ", *(clib_uint32_t *) result);
    }
    printf("\n");
}

static void test_create() {
    struct clib_container_hash_map_conf conf = {
            .hash_func = (size_t (*)(const void *, size_t, clib_uint32_t)) clib_hash_crc32_le,
            .load_factor = 0.5f,
            .key_length = sizeof(clib_uint32_t),
            .key_compare_func = memcmp,
            .initial_capacity = 10,
            .hash_seed = 0,
            .mem_malloc_func = malloc,
            .mem_free_func = free,
            .mem_copy_func = memcpy
    };
    int code = clib_container_hash_map_create_with_conf(&conf, &map);
    if (code != CLIB_RES_OK) {
        return;
    }
    printf("创建成功\n");
    show();
}


static void test_put() {
    for (int i = 0; i < 1000; ++i) {
        clib_uint32_t *value = malloc(sizeof(clib_uint32_t));
        *value = i;
        int insert_key = i;
        void *pre_data;
        int code = clib_container_hash_map_put(map, &insert_key, value, &pre_data);
        if (code != CLIB_RES_OK) {
            printf("clib_container_hash_map_put error\n");
            return;
        }
        if (pre_data != NULL) {
            free(pre_data);
        }
    }

    for (int i = 500; i < 1500; ++i) {
        clib_uint32_t *value = malloc(sizeof(clib_uint32_t));
        *value = i;
        int insert_key = i;
        void *pre_data;
        int code = clib_container_hash_map_put(map, &insert_key, value, &pre_data);
        if (code != CLIB_RES_OK) {
            printf("clib_container_hash_map_put error\n");
            return;
        }
        if (pre_data != NULL) {
            free(pre_data);
        }
    }

    for (int i = 0; i < 1400; ++i) {
        int remove_key = i;
        void *pre_data;
        int code = clib_container_hash_map_remove(map, &remove_key, &pre_data);
        if (code != CLIB_RES_OK) {
            printf("clib_container_hash_map_remove error\n");
            return;
        }
        if (pre_data != NULL) {
            free(pre_data);
        }
    }
    show();
    size_t current_size = clib_container_hash_map_get_current_size(map);
    void *pre_data_point[current_size];
    int remove_num = clib_container_hash_map_remove_all(map, NULL);
    printf("current_size %zu remove_num %d\n",current_size,remove_num);
//    if (remove_num == current_size){
//        for (int i = 0; i < remove_num; ++i) {
//            free(pre_data_point[i]);
//        }
//        show();
//    }
}


static void test_hash_map() {

    test_create();
    test_put();
}